#include "mystdio.h"
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <malloc.h>
#include <unistd.h>
#include <assert.h>

MY_file *my_fopen(const char *path, const char *mode)
{
  // 1.识别标志
  int flag = 0;
  if (strcmp(mode, "r") == 0)
    flag |= O_RDONLY;
  else if (strcmp(mode, "w") == 0)
    flag |= (O_CREAT | O_WRONLY | O_TRUNC);
  else if (strcmp(mode, "a") == 0)
    flag |= (O_CREAT | O_WRONLY | O_APPEND);
  else
  {
  }

  // 打开文件
  mode_t m = 0666;  //设置所有权 umask
  int fd = 0;
  if (flag & O_CREAT)
    fd = open(path, flag, m);
  else
    fd = open(path, flag);

  MY_file *mf = (MY_file *)malloc(sizeof(MY_file));
  if (mf == NULL)
  {
    close(fd);
    return NULL;
  }
  // 初始化
  mf->fd = fd;
  mf->flags = 0;
  mf->flags |= BUFF_NONE;
  memset(mf->buffer, '\0', sizeof(mf->buffer)); // 填充\0
  mf->cur = 0;

  return mf;
}

int my_fflush(MY_file *fp)
{
  assert(fp);
  write(fp->fd, fp->buffer, fp->cur);
  fp->cur = 0;
  fsync(fp->fd);

  return 0;
}

size_t my_fwrite(const void *ptr, size_t size, size_t nmemb, MY_file *stream)
{
  if (stream->cur == NUM)
    my_fflush(stream); // 当缓冲区满了就刷新

  // 缓冲区进行拷贝
  size_t u_size = size * nmemb;  //内容大小
  size_t ff_size = NUM - stream->cur; // 10-2==8 刷新缓冲区剩余的大小

  size_t writen = 0;

    //处理缓冲区内容大小
  if (ff_size >= u_size)
  {
    memcpy(stream->buffer + stream->cur, ptr, u_size); // 追加到buffer里ptr中的size字节

    // 更新
    stream->cur += u_size;
    writen = u_size;
  }
  else
  {
    
    memcpy(stream->buffer + stream->cur, ptr, ff_size);
    stream->cur += ff_size;
    writen = ff_size;
  }

  //缓冲区分类
  if (stream->flags & BUFF_ALL)//全刷新
  {
    if (stream->cur == NUM)
      my_fflush(stream);
  }
  else if (stream->buffer[stream->cur - 1] == '\n') //换行刷新
    my_fflush(stream);

  else //无刷新
  {
    // 自定义刷新
  }

  return writen; // 返回字节数
}



//清空后关闭
int my_fclose(MY_file *fp)
{
  assert(fp);
  if (fp->cur > 0)
    my_fflush(fp); //刷新

  close(fp->fd);  //关闭文件描述符

  free(fp);//释放缓冲区空间

  fp = NULL;
  return 0;
}
